💡 AI 인사이트

🤖 AI가 여기에 결과를 출력합니다...

댓글 커뮤니티

쿠팡이벤트

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

검색

    로딩 중이에요... 🐣

    [코담] 웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트

    17 댓글 생성 기능 (Form 기반 + API) | ✅ 편저: 코담 운영자

    17강 - 댓글 생성 기능 (Form 기반 + API)

    댓글 생성 - django form, api 개발


    ✨ 이번 강의 목표

    • Django Form 기반 댓글 입력 처리
    • Ajax 기반 댓글 생성 API 연동
    • Form 유효성 검사 + 커스텀 오류 메시지

    1. 댓글 Form 정의 (forms.py)

    from django import forms
    from .models import Comment
    
    class CommentForm(forms.ModelForm):
        class Meta:
            model = Comment
            fields = ['contents']
            labels = {"contents": ""}
            widgets = {
                "contents": forms.Textarea(attrs={
                    "placeholder": "댓글을 입력하세요...",
                    "rows": 3,
                }),
            }
    
        def clean_contents(self):
            contents = self.cleaned_data.get("contents", "").strip()
    
            if not contents:
                raise forms.ValidationError("댓글 내용을 입력해주세요.")
            if len(contents) < 2:
                raise forms.ValidationError("댓글은 최소 2자 이상 입력해야 합니다.")
            if len(contents) > 100:
                raise forms.ValidationError("댓글은 100자 이하로 입력해야 합니다.")
    
            return contents
    
    • 유효성 검사 커스텀(clean_contents)으로 강력한 입력 제어 가능
    • strip() 처리로 공백만 입력하는 경우 방지

    2. 댓글 저장 뷰 함수 (views.py)

    from django.views.decorators.http import require_POST
    from django.contrib.auth.decorators import login_required
    from django.http import JsonResponse
    from django.shortcuts import get_object_or_404
    from .forms import CommentForm
    from .models import Post
    from .api import serializers
    from django_instagram.utils import form_errors_to_string
    
    @require_POST
    @login_required
    def comment_create(request, post_id):
        if not request.user.is_authenticated:
            return JsonResponse({"success": False, "message": "로그인이 필요합니다."}, status=401)
    
        post = get_object_or_404(Post, pk=post_id)
        form = CommentForm(request.POST)
    
        if form.is_valid():
            comment = form.save(commit=False)
            comment.author = request.user
            comment.post = post
            comment.save()
            return JsonResponse({"success": True, "comment": serializers.CommentSerializer(comment).data})
    
        return JsonResponse({
            "success": False,
            "message": "댓글 등록 실패",
            "errors": form_errors_to_string(form)
        }, status=400)
    

    3. URL 설정 (posts/urls.py)

    path('<int:post_id>/comment_create/', views.comment_create, name='comment_create'),
    
    • post_id를 URL에 포함해 해당 포스트에 댓글 연결
    • RESTful하게 구성 (명확하고 유지보수 편리)

    4. 템플릿 index.html 내 폼 예시

    <form method="POST" class="comment-form">
      <textarea name="contents" rows="3" placeholder="댓글을 입력하세요..."></textarea>
      <input type="submit" value="댓글 등록" class="bg-blue-500 text-white px-2 py-1 rounded">
    </form>
    

    실제 동작은 JS에서 fetch() 요청을 통해 처리되며 이 폼은 Ajax 전송 대상


    5. 유틸 함수 (utils.py)

    def form_errors_to_string(form):
        """
        Django Form의 errors를 하나의 문자열로 변환하는 함수.
        """
        return ", ".join([msg for msgs in form.errors.values() for msg in msgs])
    
    • 유효성 실패 시, 여러 메시지를 하나의 문자열로 만들어서 alert에 표시

    6. JS 파일: 댓글 등록 (loadMorePosts.js)

    async function commentCreate(postId, csrfToken, event) {
      event.preventDefault();
    
      const form = event.currentTarget.closest('form');
      const contents = form.querySelector('textarea[name="contents"]').value.trim();
      if (!contents) {
        alert("댓글을 입력하세요.");
        return;
      }
    
      try {
        const response = await fetch(`/posts/${postId}/comment_create/`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'X-CSRFToken': csrfToken,
          },
          body: new URLSearchParams({ contents }),
        });
    
        const data = await response.json();
    
        if (data.success) {
          const articleElement = document.querySelector(`#article-${postId}`);
          const commentListElement = articleElement.querySelector('.comment-list');
          commentListElement.insertAdjacentHTML(
            'afterbegin',
            commentListElement(data.comment, csrfToken, data.comment.author.username)
          );
          form.reset();
        } else if (data.errors) {
          alert(data.errors);
        }
      } catch (error) {
        console.error('댓글 등록 중 오류 발생:', error);
        alert('댓글 등록에 실패했습니다.');
      }
    }
    

    ✅ 정리

    • Form → Ajax → View → 저장 → JsonResponse 구조로 처리
    • CommentForm에서 유효성 검증으로 클린한 입력 보장
    • JS에서 댓글 등록 후 실시간 렌더링까지 구현 가능
    • 다음 강의에서는 댓글 삭제 및 좋아요 기능을 추가합니다
    TOP
    preload preload